import * as d3 from "d3";

export class HeatMap {
    constructor(container) {
        this.container = container;
        this.margin = { top: 50, right: 50, bottom: 50, left: 70 };
        this.width = 400;
        this.height = 250;
        
        this.svg = d3.select(container)
            .append('svg')
            .attr('width', this.width + this.margin.left + this.margin.right)
            .attr('height', this.height + this.margin.top + this.margin.bottom)
            .append('g')
            .attr('transform', `translate(${this.margin.left},${this.margin.top})`);

        this.colorScale = d3.scaleSequential()
            .interpolator(d3.interpolateBlues)  
            .domain([0, 50]); 
            
        // 添加图表边框和背景
        this.svg.append('rect')
            .attr('width', this.width)
            .attr('height', this.height)
            .attr('fill', '#ffffff')
            .attr('stroke', '#e0e0e0')
            .attr('stroke-width', 1);
            
        // 网格线
        this.svg.selectAll('.grid-line')
            .style('stroke', '#f5f5f5')
            .style('stroke-width', 1);
            
        // 坐标轴
        this.svg.selectAll('.axis')
            .style('font-family', 'Arial, sans-serif')
            .style('font-size', '12px')
            .style('color', '#666666');
            
        // 单元格样式
        this.svg.selectAll('rect.cell')
            .attr('rx', 2)  
            .attr('ry', 2)
            .style('stroke', '#ffffff')
            .style('stroke-width', 2)
            .style('transition', 'all 0.3s ease');
            
        // 数值标签样式
        this.svg.selectAll('.label')
            .style('font-family', 'Arial, sans-serif')
            .style('font-weight', 500)
            .style('letter-spacing', '0.5px');
            
        // 添加阴影效果
        this.svg.append('defs')
            .append('filter')
            .attr('id', 'shadow')
            .append('feDropShadow')
            .attr('dx', 0)
            .attr('dy', 1)
            .attr('stdDeviation', 2)
            .attr('flood-opacity', 0.1);
            
        // 添加渐变背景
        const gradient = this.svg.append('defs')
            .append('linearGradient')
            .attr('id', 'bg-gradient')
            .attr('x1', '0%')
            .attr('y1', '0%')
            .attr('x2', '100%')
            .attr('y2', '100%');
            
        gradient.append('stop')
            .attr('offset', '0%')
            .attr('style', 'stop-color: #f8f9fa; stop-opacity: 1');
            
        gradient.append('stop')
            .attr('offset', '100%')
            .attr('style', 'stop-color: #ffffff; stop-opacity: 1');

        // 添加提示框
        this.tooltip = d3.select('body')
            .append('div')
            .attr('class', 'heatmap-tooltip')
            .style('position', 'fixed')
            .style('visibility', 'hidden')
            .style('z-index', '10000')
            .style('background', 'rgba(255, 255, 255, 0.95)')
            .style('border-radius', '4px')
            .style('box-shadow', '0 2px 12px rgba(0,0,0,0.1)')
            .style('padding', '12px 16px')
            .style('font-family', 'Arial, sans-serif')
            .style('font-size', '13px')
            .style('line-height', '1.4')
            .style('color', '#333')
            .style('border', '1px solid #eaeaea')
            .style('pointer-events', 'none');  

        this.handlers = {};
    }

    on(eventName, handler) {
        this.handlers[eventName] = handler;
    }

    highlight(major) {
        if (!this.svg || !this.data) return;
        
        if (!major) {
            this.update(this.data);  
            return;
        }
        
        this.svg.selectAll('rect')
            .transition()
            .duration(300)
            .style('opacity', d => d.major === major ? 1 : 0.3)
            .style('stroke', d => d.major === major ? '#ffd700' : 'white')
            .style('stroke-width', d => d.major === major ? 3 : 2);

        // 同时调整文本标签的显示
        this.svg.selectAll('.label')
            .transition()
            .duration(300)
            .style('opacity', d => {
                if (!major) {
                    // 恢复原有的显示逻辑
                    const majorValues = this.data.filter(item => item.major === d.major)
                        .map(item => item.value);
                    return Math.max(...majorValues) === d.value ? 1 : 0;
                }
                // 高亮状态下只显示选中专业的标签
                return d.major === major ? 1 : 0;
            });
    }

    update(data) {
        this.data = data;  // 保存数据以供重绘使用
        this.svg.selectAll('*').remove();  // 清除所有元素
        // 准备数据
        const majors = ['文科类', '理科类', '工科类', '艺术类', '医学类'];
        const frequencies = ['每天都用', '每周3-5次', '每周1-2次', '每月1-2次', '很少使用'];
        
        // 转换数据格式
        const heatmapData = majors.flatMap(major => {
            const majorData = data.find(d => d.major === major);
            const total = Object.values(majorData.frequencies).reduce((a, b) => a + b, 0);
            
            return frequencies.map(freq => ({
                major: major,
                frequency: freq,
                value: (majorData.frequencies[freq] / total) * 100  
            }));
        });

        // 创建比例尺
        const x = d3.scaleBand()
            .domain(majors)
            .range([0, this.width])
            .padding(0.05);

        const y = d3.scaleBand()
            .domain(frequencies)
            .range([0, this.height])
            .padding(0.05);

        // 创建颜色比例尺
        const colorScale = d3.scaleSequential()
            .domain([0, 50])  
            .interpolator(d => {
                return d3.interpolate(
                    '#f7fbff',  
                    '#084594'   
                )(d);
            });

        // 绘制热力图方格
        this.svg.selectAll('rect')
            .data(heatmapData)
            .join('rect')
            .attr('x', d => x(d.major))
            .attr('y', d => y(d.frequency))
            .attr('width', x.bandwidth())
            .attr('height', y.bandwidth())
            .attr('fill', d => colorScale(d.value))
            .style('stroke', 'white')
            .style('stroke-width', 2); 

        // 添加数值标签
        this.svg.selectAll('.label')
            .data(heatmapData)
            .join('text')
            .attr('class', 'label')
            .attr('x', d => x(d.major) + x.bandwidth() / 2)
            .attr('y', d => y(d.frequency) + y.bandwidth() / 2)
            .attr('text-anchor', 'middle')
            .attr('dominant-baseline', 'middle')
            .style('font-size', '12px')
            .style('font-weight', 'bold')
            .style('fill', d => d.value > 25 ? 'white' : 'black')
            .style('pointer-events', 'none')
            .style('opacity', d => {
                const majorValues = heatmapData.filter(item => item.major === d.major)
                    .map(item => item.value);
                return Math.max(...majorValues) === d.value ? 1 : 0;
            })
            .text(d => {
                const majorValues = heatmapData.filter(item => item.major === d.major)
                    .map(item => item.value);
                return Math.max(...majorValues) === d.value ? d.value.toFixed(1) + '%' : '';
            });

        // 添加动态效果的鼠标交互
        this.svg.selectAll('rect')
            .on('mouseover', (event, d) => {
                // 高亮当前方格
                d3.select(event.currentTarget)
                    .transition()
                    .duration(200)
                    .style('stroke', '#ffd700')
                    .style('stroke-width', 3)
                    .style('filter', 'brightness(1.1)');

                // 显示提示框
                this.tooltip
                    .style('visibility', 'visible')
                    .style('opacity', 0)
                    .html(`专业：${d.major}<br>频率：${d.frequency}<br>占比：${d.value.toFixed(1)}%`)
                    .style('left', `${event.clientX + 10}px`)
                    .style('top', `${event.clientY - 10}px`)
                    .transition()
                    .duration(200)
                    .style('opacity', 1);

                // 触发专业悬停事件
                this.handlers['majorHover']?.(d.major);
            })
            .on('mousemove', (event) => {
                this.tooltip
                    .style('left', `${event.clientX + 10}px`)
                    .style('top', `${event.clientY - 10}px`);
            })
            .on('mouseout', (event, d) => {
                // 恢复方格样式
                d3.select(event.currentTarget)
                    .transition()
                    .duration(200)
                    .style('stroke', 'white')
                    .style('stroke-width', 2)
                    .style('filter', 'none');

                // 隐藏提示框
                this.tooltip
                    .transition()
                    .duration(200)
                    .style('opacity', 0)
                    .on('end', () => this.tooltip.style('visibility', 'hidden'));

                // 触发专业移出事件
                this.handlers['majorOut']?.();
            })
            .on('click', (event, d) => {
                if (this.handlers['majorClick']) {
                    this.handlers['majorClick'](d.major);
                }
            })
            .style('cursor', 'pointer');

        // 添加底部X轴
        this.svg.append('g')
            .attr('transform', `translate(0,${this.height})`)  
            .style('font-size', '12px')
            .call(d3.axisBottom(x))
            .selectAll('text')  
            .style('text-anchor', 'middle')  
            .attr('transform', `translate(0,10)`);

        // 添加左侧Y轴
        this.svg.append('g')
            .style('font-size', '12px')
            .call(d3.axisLeft(y))
            .selectAll('text');

        // 添加标题
        this.svg.append('text')
            .attr('x', this.width / 2)
            .attr('y', -20)
            .attr('text-anchor', 'middle')
            .style('font-size', '20px')
            .style('font-weight', 'bold')
            .text('各专业AI工具使用频率分布');

        // 添加悬停效果
        this.svg.selectAll('rect.cell')
            .on('mouseover', function(event, d) {
                d3.select(this)
                    .transition()
                    .duration(200)
                    .style('filter', 'url(#shadow)')
                    .style('transform', 'scale(1.02)');
            })
            .on('mouseout', function() {
                d3.select(this)
                    .transition()
                    .duration(200)
                    .style('filter', 'none')
                    .style('transform', 'scale(1)');
            });
    }
} 